package com.yunc.common.ftp;

import com.yunc.common.properties.FTPPro;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * FTPClient 工厂
 * @Auther: hrabbit
 * @Date: 2018-12-03 3:41 PM
 */
public class FTPClientFactory implements PoolableObjectFactory<FTPClient> {

    private static final Logger logger = LogManager.getLogger(FTPClientFactory.class);

    private FTPPro ftpPro;

    public FTPClientFactory(FTPPro ftpPro) {
        this.ftpPro = ftpPro;
    }

    @Override
    public FTPClient makeObject() throws Exception {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding(ftpPro.getEncoding());
        ftpClient.setConnectTimeout(ftpPro.getClientTimeout());
        // 单位是秒
        ftpClient.setControlKeepAliveTimeout(60 * 60);
        try {
            ftpClient.connect(ftpPro.getHost(), ftpPro.getPort());
            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                logger.warn("FTPServer refused connection");
                return null;
            }
            boolean result = ftpClient.login(ftpPro.getUserName(), ftpPro.getPassWord());
            ftpClient.setFileType(ftpPro.getTransferFileType());
            if (!result) {
                logger.warn("ftpClient login failed... username is {}", ftpPro.getUserName());
            }
        } catch (Exception e) {
            logger.error("create ftp connection failed...{}", e);
            throw e;
        }

        return ftpClient;
    }

    @Override
    public void destroyObject(FTPClient ftpClient) throws Exception {
        try {
            if(ftpClient != null && ftpClient.isConnected()) {
                ftpClient.logout();
            }
        } catch (Exception e) {
            logger.error("ftp client logout failed...{}", e);
            throw e;
        } finally {
            if(ftpClient != null) {
                ftpClient.disconnect();
            }
        }

    }

    @Override
    public boolean validateObject(FTPClient ftpClient) {
        try {
            return ftpClient.sendNoOp();
        } catch (Exception e) {
            logger.error("Failed to validate client: {}");
        }
        return false;
    }

    @Override
    public void activateObject(FTPClient obj) throws Exception {
        //Do nothing

    }

    @Override
    public void passivateObject(FTPClient obj) throws Exception {
        //Do nothing

    }

}
